package com.javiercp.ayudaapp;

import java.text.DateFormat;
import java.util.Date;
import java.util.List;

import com.javiercp.ayudaapp.LocationService.LocationBinder;
import com.javiercp.ayudaapp.location.LocationHelper;
import com.javiercp.ayudaapp.mail.MailManager;
import com.javiercp.ayudaapp.mail.MailMessage;
import com.javiercp.ayudaapp.preferences.ContactData;
import com.javiercp.ayudaapp.preferences.ContactDataList;
import com.javiercp.ayudaapp.preferences.ContactsPreferenceInflater;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;

public class SendActivity extends Activity {
	
	private static final int NUMBER_LOCATION_TRIES = 2;
	private static final int LOCATION_FIXES_THRESHOLD = 5;
	private static final float LOCATION_ACCURACY_THRESHOLD = 10;

	private static final long UPDATE_TIME = 15000;

	private EditText mprogressLog;
	
	private LocationBinder mBinder = null;
	private Location mlocation = null;
	private boolean mlocationGood = true;
	private int mnumLocationFixes = 0;
	
	private ContactDataList msmsRecipientList = null;
	private ContactDataList memailRecipientList = null;
	
	private Handler mhandler = new Handler();
	private int mhandlerRuns = 0;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.send);
        Log.i(MyConstants.LOGTAG, "onCreate");
        
        Log.i(MyConstants.LOGTAG, "Setting up UI");
        mprogressLog = (EditText)findViewById(R.id.progressLog); 
        
        Log.i(MyConstants.LOGTAG, "Creating location service");
        Intent intent = new Intent(this, LocationService.class);
        getApplicationContext().startService(intent);
        addTextTE("INIT LOCATION SERVICE");
        
        loadRecipientsData(getString(R.string.PHONE_LIST_PREFERENCE_KEY));
        addTextTE("INIT READING SMS RECIPIENTS");
        
        loadRecipientsData(getString(R.string.EMAIL_LIST_PREFERENCE_KEY));
        addTextTE("INIT READING EMAIL RECIPIENTS");
        
        mhandler.postDelayed(mcheckCompletionTask, UPDATE_TIME);
    }

    
    private boolean isLocationGoodEnough(Location loc, int locUpdates) {
    	if (loc == null) return false;
    	
    	if (locUpdates > LOCATION_FIXES_THRESHOLD) return true;
    	
    	if (loc.hasAccuracy()) {
    		if (loc.getAccuracy() < LOCATION_ACCURACY_THRESHOLD) return true;
    	}
    	
    	return false;
    }
      
    @Override
    protected void onResume() {
    	super.onResume();
    	Intent intent = new Intent(this, LocationService.class);
    	getApplicationContext().bindService(intent, mConnection, 0);
    };
    
    @Override
    protected void onPause() {
    	super.onPause();
    	getApplicationContext().unbindService(mConnection);
    };
    
    @Override
    protected void onDestroy() {
    	super.onDestroy();
    	
		if (mBinder != null) {
			mBinder.stop();
		}
		
    	if (mBinder != null && !mBinder.isRunning()) {
    		getApplicationContext().stopService(new Intent(this, LocationService.class));
    	}
    };
    
    ServiceConnection mConnection = new ServiceConnection() {	
		@Override
		public void onServiceDisconnected(ComponentName name) {
			mBinder.registerHandler(null);
			mBinder = null;		
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder binder) {
			mBinder = (LocationBinder)binder;
			mBinder.registerHandler(mHandler);
			
			mBinder.init();
			addTextTE("WAITING FOR LOCATION FIX");
		}
	};
	
	private final Handler mHandler = new Handler() {
		@Override
		public void dispatchMessage(android.os.Message msg) {
			switch (msg.what) {
			case MyConstants.GOT_LOCATION:			
				mlocation = LocationHelper.deserialize(msg.getData().getString(MyConstants.LOCATION_KEY));
				mnumLocationFixes++;
				addTextTE("GOT LOCATION FIX");
				
				//Toast.makeText(getApplicationContext(), msg.getData().getString(MyConstants.LOCATION_KEY), Toast.LENGTH_SHORT).show();
				break;
			}
		};	
	};
    
    //------------------------------------------------------------------ 
	
	private Runnable mcheckCompletionTask = new Runnable() {	
		@Override
		public void run() {
			synchronized (this) {
				mhandlerRuns++;
				
				if (!isLocationGoodEnough(mlocation, mnumLocationFixes)) {
					if (mhandlerRuns < NUMBER_LOCATION_TRIES) {
						mhandler.postDelayed(this, UPDATE_TIME);
						addTextTE("LOCATION FIX NOT GOOD ENOUGH");
						addTextTE("WAIT FOR LOCATION FIX");
						return;
					}
					else {
						mlocation = mBinder.getLocationFast();
						mlocationGood = false;
						addTextTE("LOCATION FIX NOT GOOD ENOUGH");
						addTextTE("GETTING ESTIMATE LOCATION FIX");
					}
				}
				
				if (mBinder != null) {
					mBinder.stop();
				}
				addTextTE("STOP LOCATION SERVICE");
								
				if (PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(getString(R.string.MAIL_SEND_PREF), false))
				{			
					sendMailToContacts();
					addTextTE("START SENDING EMAIL TO RECIPIENTS");
				}
			}
		}
	};
    
	private void sendMailToContacts() {
	
		AsyncTask<ContactDataList, Void, Boolean> task;
	 	
    	task = new AsyncTask<ContactDataList, Void, Boolean>() {
			@Override
			protected Boolean doInBackground(ContactDataList... params) {
				
				String host = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(getString(R.string.HOST_PREF), "");
				String port = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(getString(R.string.PORT_PREF), "");
				String socketFactoryPort = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(getString(R.string.SOCKETF_PREF), "");
				String user = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(getString(R.string.USER_PREF), "");
				String passwd = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(getString(R.string.PASSWORD_PREF), "");
				boolean auth = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(getString(R.string.AUTH_PREF), true);
				boolean debug = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(getString(R.string.DEBUG_PREF), false);
				
				MailMessage message = new MailMessage();
				MailManager mailManager = new MailManager(user, passwd, host, port, socketFactoryPort, auth, debug);
				
				List<ContactData> contactList = ((ContactDataList) params[0]).getContacts();
				
				message.setFrom(user);
				message.setSubject(getMailSubject());				
				message.setBody(getMailBody());
				message.setTo(new String[contactList.size()]);
				
				int i = 0;
				for (ContactData cf : contactList) {
					message.getTo()[i] = cf.getName();
					i++;
				}
				
				try {
					mailManager.send(message);	
				} catch (Exception ex) {
					return false;
				}
				
				return true;
			}
			
    		@Override
    		protected void onPostExecute(Boolean result) {          			
    			if (result) {
    				addTextTE("FINISH SENDING EMAIL TO RECIPIENTS");
    			}
    			else {
    				addTextTE("ERROR SENDING EMAIL TO RECIPIENTS");
    			}
    		}
    	};
	        
        task.execute(memailRecipientList);
        addTextTE("INIT SENDING EMAIL TO RECIPIENTS");
	}
	
	private String getMailSubject() {
		return "HELP";
	}
	
	private String getMailBody() {
		String retValue = "";
		
		if (mlocationGood) {
			retValue = retValue + "This is my location.\n\n";
		} else {
			retValue = retValue + "I couldn't get a good location fix. This is my last known location.\n\n";
		}
		
		retValue = retValue + LocationHelper.locationToString(mlocation) + "\n";
		
		retValue = retValue + LocationHelper.reverseGeolocate(this, mlocation);
		
		return retValue;
	}

    private void loadRecipientsData(final String configKey) {
    	AsyncTask<String, Void, ContactDataList> task;
    		 	
    	task = new AsyncTask<String, Void, ContactDataList>() {
			@Override
			protected ContactDataList doInBackground(String... params) {
				String xml = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(params[0], "");
				
				ContactsPreferenceInflater cf = ContactsPreferenceInflater.getInstance();
		        
				return cf.deserialice(xml);
			}
			
    		@Override
    		protected void onPostExecute(ContactDataList result) {      
    			if (configKey.equals(getString(R.string.PHONE_LIST_PREFERENCE_KEY))) {
    				msmsRecipientList = result;
    				addTextTE("FINISH READING SMS RECIPIENTS");
    			}
    			
    			if (configKey.equals(getString(R.string.EMAIL_LIST_PREFERENCE_KEY))) {
    				memailRecipientList = result;
    				addTextTE("FINISH READING EMAIL RECIPIENTS");
    			}
    		}
    	};
	        
        task.execute(configKey);
    }
	
	private String addTextTE(String text) {
		String currText;
		
		if (mprogressLog == null) {
			mprogressLog = (EditText)findViewById(R.id.progressLog); 
		}
        currText = mprogressLog.getText() + DateFormat.getTimeInstance().format(new Date()) + " - " + text + "\n";
        mprogressLog.setText(currText);
        mprogressLog.setSelection(mprogressLog.getText().length());
        
        return currText;
	}	
}


